﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dracham.Classes
{
    public enum AIStance : int
    {
        Friendly = 0,
        Defensive = 1,
        Aggresive = 2

    }

    public partial class Creature : MobileObject
    {
        public Item[] Drops { get; set; }
        public DateTime LastAttack { get; set; }
        public Boolean IsCoward { get; set; }
        public Boolean InCombat { get; set; }
        public Object Target { get; set; }
        public Queue<PathNode> WalkPath { get; set; }
        public int CurrentHitpoints { get; set; }
        public int CurrentMagicpoints { get; set; }

        private Position targetPosition;

        public override void  Initialize()
        {
            this.WalkPath = new Queue<PathNode>();
            this.Drops = Treasure.LoadByObject(this).CalculateLoot();
            this.CurrentHitpoints = this.Hitpoints;
            base.Initialize();
        }

        public override void Expire()
        {
            base.Expire();

            foreach (Account acc in this.Position.Zone.GetCharactersInZone())
            {
                if (acc.Client != null)
                {
                    acc.Client.Invoke(MessageType.MobDeath,
                        new NetworkParameter(this.Id.ToString(), 36));
                }
            }
        }

        public void Pulse()
        {
            if (!this.HasExpired)
            {
                if (Utility.Random(100) > 90)
                {
                    foreach (Account acc in this.Position.Zone.GetCharactersInZone())
                    {
                        String msg = "WRYYYYYYY!";
                        acc.Client.Invoke(MessageType.ChatMessage,
                            new NetworkParameter(this.Name, 20),
                            new NetworkParameter(msg.Length.ToString(), 10),
                            new NetworkParameter(msg, msg.Length));
                    }
                }

                Boolean hasActed = false;

                while (!hasActed)
                {
                    if (this.Target == null)
                    {
                        Account[] possibleTargets = this.Position.Zone.GetCharactersInZone()
                            .Where(a => a.CurrentCharacter.Distance(this) <= 10)
                            .OrderBy(a => a.CurrentCharacter.Distance(this)).ToArray();

                        if (possibleTargets.Count() > 0)
                        {
                            Character c = possibleTargets.First().CurrentCharacter;

                            this.InCombat = true;
                            this.Target = c;
                            this.targetPosition = (Position)c.Position.Clone();
                        }
                        else
                        {
                            if (GameWorld.Spawns.First(s => s.Object.Id == this.Id).Position.Equals(this.Position))
                            {
                                hasActed = true;
                            }
                            else
                            {
                                this.ReturnToSpawn();
                            }
                        }

                    }

                    if (this.Target != null)
                    {
                        if (!this.Target.Position.IsEqual(this.targetPosition))
                        {
                            if (this.Target.Position.ZoneId != this.targetPosition.ZoneId)
                            {
                                this.InCombat = false;
                                this.Target = null;
                                this.targetPosition = null;
                                this.ReturnToSpawn();
                            }
                            else
                            {
                                this.targetPosition = (Position)this.Target.Position.Clone();
                                this.FillWalkPath(Pathfinder.FindPath(this.Position, this.targetPosition));
                            }
                        }
                    }

                    if (this.WalkPath.Count > 0)
                    {
                        Position oldPos = (Position)this.Position.Clone();
                        this.Position = this.WalkPath.Dequeue().Position;

                        foreach (Account acc in this.Position.Zone.GetCharactersInZone())
                        {
                            List<NetworkParameter> p = new List<NetworkParameter>();
                            p.Add(new NetworkParameter(this.Id.ToString(), 36));
                            p.Add(new NetworkParameter(this.ModelId.ToString(), 20));
                            p.Add(new NetworkParameter(this.Position.ZoneId, 20));
                            p.AddRange(oldPos.GetNetworkDescription());
                            p.AddRange(this.Position.GetNetworkDescription());
                            acc.Client.Invoke(MessageType.MobMovement, p.ToArray());
                        }

                        hasActed = true;
                    }
                    else
                    {
                        if (this.targetPosition != null)
                        {
                            if (this.Position.Distance(this.targetPosition) > 1.5)
                            {
                                this.FillWalkPath(Pathfinder.FindPath(this.Position, this.targetPosition));
                            }
                            else
                            {
                                if (DateTime.Now.CompareTo(this.LastAttack.AddSeconds(1)) > 0)
                                {
                                    Account acc = GameWorld.Accounts.SingleOrDefault(a => a.CurrentCharacter == (this.Target as Character));

                                    if (acc != null)
                                    {
                                        if (!acc.CurrentCharacter.HasExpired)
                                        {
                                            FightHandler.Instance.Fight(this, acc.CurrentCharacter, GameWorld.SpellPool.SingleOrDefault(s => s.Id == 1));
                                            acc.CurrentCharacter.SendPartialData(acc.Client, "CurrentHitpoints");
                                        }
                                        else
                                        {
                                            this.Target = null;
                                            this.targetPosition = null;
                                        }
                                    }

                                    this.LastAttack = DateTime.Now;
                                }
                            }
                        }
                    }
                }
            }
        }
        
        public void FillWalkPath(PathNode[] path)
        {
            this.WalkPath.Clear();

            for (int i = 1; i < path.Length - 1; i++)
            {
                if (path[i] != null)
                    this.WalkPath.Enqueue(path[i]);
            }
        }

        public void ReturnToSpawn()
        {
            this.FillWalkPath(Pathfinder.FindPath(this.Position,
                GameWorld.Spawns.First(s => s.Object.Id == this.Id).Position));
        }
    }

    public class PulseTimer : GameTimer
    {
        public Zone Zone { get; set; }

        public PulseTimer(Zone zone)
        {
            this.Zone = zone;
            this.Interval = 520;
            this.LastRun = DateTime.Now;
        }

        public override void Run()
        {
            foreach (Creature c in this.Zone.GetCreaturesInZone())
            {
                c.Pulse();
            }
        }
    }
}
